#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>
using namespace std;
#define NUM 4

// pthread_mutex_t _mtx;
// pthread_cond_t _cond;

class Cond
{
public:
    Cond()
    {
        pthread_mutex_init(&_mtx, nullptr);
        pthread_cond_init(&_cond, nullptr);
    }
    void Cond_signal()
    {
        // 在cond 等待队列中唤醒第一个线程
        pthread_cond_signal(&_cond);

        // 在cond 等待队列中唤醒所有线程
        // pthread_cond_broadcast(&_cond);
    }
    void Cond_wait()
    {
        pthread_cond_wait(&_cond, &_mtx);
    }
    ~Cond()
    {
        pthread_mutex_destroy(&_mtx);
        pthread_cond_destroy(&_cond);
    }

private:
    pthread_mutex_t _mtx;
    pthread_cond_t _cond;
    // 条件变量之中存在一个等待队列
};

void *ctrl_thread(void *args)
{
    // string msg = *(string *)args;
    Cond* c = (Cond*)args;
    while (true)
    {
        // 在cond 等待队列中唤醒线程
        c->Cond_signal();
        cout << "signal to worker success" << endl;
        sleep(1);
    }
}

void *work_thread_one(void *args)
{
    // string msg = *(string *)args;
    Cond* c = (Cond*)args;
    while (true)
    {
        c->Cond_wait();
        cout << "work_thread_one" << endl;
        // cout << "I am process A" << endl;
    }
}

void *work_thread_two(void *args)
{
    // string msg = *(string *)args;
    Cond* c = (Cond*)args;
    while (true)
    {
        c->Cond_wait();
        cout << "work_thread_two" << endl;
        // cout << "I am process B" << endl;
    }
}

void *work_thread_three(void *args)
{
    // string msg = *(string *)args;
    Cond *c = (Cond *)args;
    while (true)
    {
        c->Cond_wait();
        cout << "work_thread_three" << endl;
    }
}

int main()
{
    Cond *c = new Cond();
    // 创建线程
    pthread_t tid[NUM];
    void *(*handler[NUM])(void *) = {ctrl_thread, work_thread_one, work_thread_two, work_thread_three};
    // string thread_num[NUM] = {"main 1", "child 1", "child 2", "child 3"};
    for (int i = 0; i < NUM; ++i)
    {
        pthread_create(tid + i, nullptr, handler[i], (void *)c);
        // pthread_create(tid + i, nullptr, handler[i], (void *)(thread_num + i));
    }
    for (int i = 0; i < NUM; ++i)
    {
        pthread_join(tid[i], nullptr);
    }

    delete c;
    return 0;
}
